/*
 * wcserv.c
 *
 *  Created on: Apr 1, 2012
 *      Author: root
 */

#include    "unp.h"

void sig_chld(int signo);

int
main(int argc, char **argv)
{
    int                    listenfd, connfd;

    int line_count=0;
    int byte_count=0;
    int all_bytecount=0;
    int all_wordcount=0;

    const int on=1;
    pid_t                childpid;
    socklen_t            clilen;
    struct sockaddr_in    cliaddr, servaddr;
    char        buf[MAXLINE];
    char        buf1[MAXLINE];
    char        buf2[MAXLINE];

    //void                sig_chld(int);
    ssize_t        n;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);

    Setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on, sizeof(on));


    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

    Listen(listenfd, LISTENQ);

    Signal(SIGCHLD, sig_chld);    /* must call waitpid() */

    for ( ; ; ) {

        clilen = sizeof(cliaddr);
        if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0)
        {
        	Setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on, sizeof(on));

            if (errno == EINTR)
            {

                continue;        /* back to for() */
            }
            else
                err_sys("accept error");
        }
        if ( (childpid = Fork()) == 0) {    /* child process */
            Close(listenfd);    /* close listening socket */

            //str_echo(connfd);    /* process the request */
            again:
                while ( (n = read(connfd, buf, MAXLINE)) > 0)
                {
                    if(!strcmp(buf,".\n")) // if client send "." exit client message
                    {
                         //
                         // if client connection exit => all byte,
                         //  					all word , all line #
                         //						  send to client
                    	printf("------close client------\n\n");
                        sprintf(buf,"all byte count : %d , all word count : %d , all line count : %d\n",all_bytecount,all_wordcount,line_count);
                        Fputs(buf,stdout);
                        printf("\n");
                        Writen(connfd, buf, strlen(buf));
                        memset(buf,0,strlen(buf));
                        break;
                    }
                    line_count++;  // add line count


                    printf("message from client : %s",buf);
                    byte_count=strlen(buf)-1; // byte count
                    sprintf(buf2,"%s",buf);
                    char *token=NULL;
                    char s1[]="\n";

                    token=strtok(buf2,s1);
                    while(token !=NULL)
                    {
                    token = strtok(NULL,s1); // for \n divide.
                    }

                    //Fputs(buf2,stdout);
                    char s2[]=" \n";

                    int word_count=0;
                    token=strtok(buf,s2);
                    while(token !=NULL)
                    {

                        token = strtok(NULL,s2);
                        word_count++;
                    }
                    printf("line count : %d , ", line_count);
                    printf("word count : %d , ",word_count);
                    printf("byte count : %d\n\n",byte_count);

                    all_wordcount+=word_count; // calculate all_word count
                    all_bytecount+=byte_count; // calculate all_byte count

                    sprintf(buf1,"      word count : %d, byte_count : %d\n",word_count,byte_count);
                    // buf1 add the calculation

                    memset(buf,0,strlen(buf)); // buf initialization
                    sprintf(buf,"%s",buf2); // if space divide message, word is cut,
                    						// for cut word prevent // a man => a

                    strcat(buf,buf1);
                    //Fputs(buf,stdout);
                    Writen(connfd, buf, strlen(buf));
                    memset(buf,0,strlen(buf)); //buf initialization
                    memset(buf1,0,strlen(buf1)); // buf1 initialization
                    //Fputs(buf,stdout);

                }
                if (n < 0 && errno == EINTR)
                    goto again;
                else if (n < 0)
                    err_sys("str_echo: read error");
            exit(0);
        }
        Close(connfd);            /* parent closes connected socket */
    }
}

void sig_chld(int signo)
{
    pid_t    pid;
    int stat;

    while((pid=waitpid(-1,&stat,WNOHANG))>0)
        printf("child %d terminated\n",pid);

    return;
}
